iT邦幫忙

0

Golang - GraphQL - Auth Endpoints

  • 分享至 

  • xImage
  •  

Introduction

上一篇已經完成了 JWT 的部分功能
接著開始完善 JWT 功能

Sample Code

完成後的資料夾結構如下
https://ithelp.ithome.com.tw/upload/images/20230508/20118878nqWqJQW9IB.png

CreateUser

schema.resolvers.go 實現 CreateUser funciotn

func (r *mutationResolver) CreateUser(ctx context.Context, input model.NewUser) (string, error) {
	var user users.User
	user.Username = input.Username
	user.Password = input.Password
	user.Create()
	token, err := jwt.GenerateToken(user.Username)
	if err != nil{
		return "", err
	}
	return token, nil
}

$ go run server.go 測試一下 CreateUser 能不能成功
打開 http://localhost:8080/ 輸入

mutation {
  createUser(input: {username: "user1", password: "123"})
}

接著會得到一串 JWT string

{
  "data": {
    "createUser": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODM2MjU1ODcsInVzZXJuYW1lIjoidXNlcjEifQ.FUO8LH8G_FioVmVVMqVhQiqEndmbK_QIdq5KlHFWtwY"
  }
}

Login

這階段開始實作當輸入了正確的帳號密碼,就會產生 JWT Token 給 user
internal/users/users.go 實作 Authenticate function
不過要注意一下...這段 Query 是練習做實驗才用的,不然這樣是有暴露密碼的危險性

func (user *User) Authenticate() bool {
	statement, err := mig.Db.Prepare("select Password from Users WHERE Username = ?")
	if err != nil {
		log.Fatal(err)
	}
	row := statement.QueryRow(user.Username)

	var hashedPassword string
	err = row.Scan(&hashedPassword)
	if err != nil {
		if err == sql.ErrNoRows {
			return false
		} else {
			log.Fatal(err)
		}
	}

	return CheckPasswordHash(user.Password, hashedPassword)
}

schema.resolvers.go 實作 Login function

func (r *mutationResolver) Login(ctx context.Context, input model.Login) (string, error) {
	var user users.User
	user.Username = input.Username
	user.Password = input.Password
	correct := user.Authenticate()
	if !correct {
		// 1
		return "", &users.WrongUsernameOrPasswordError{}
	}
	token, err := jwt.GenerateToken(user.Username)
	if err != nil{
		return "", err
	}
	return token, nil
}

internal/users/errors.go 處理錯誤回傳

package users

type WrongUsernameOrPasswordError struct{}

func (m *WrongUsernameOrPasswordError) Error() string {
	return "wrong username or password"
}

schema.resolvers.go 處理 Refresh Token

func (r *mutationResolver) RefreshToken(ctx context.Context, input model.RefreshTokenInput) (string, error) {
	username, err := jwt.ParseToken(input.Token)
	if err != nil {
		return "", fmt.Errorf("access denied")
	}
	token, err := jwt.GenerateToken(username)
	if err != nil {
		return "", err
	}
	return token, nil
}

Reference


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言